package tech.aistar.day12;

import tech.aistar.design.singleton.version04.Single04Demo;
import tech.aistar.design.singleton.version05.Single05Demo;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * 本类用来演示: 反射破坏封装性
 *
 * @author: success
 * @date: 2021/3/23 10:56 上午
 */
public class ReflectDemo {
    public static void main(String[] args) {
        //Single04Demo单例的 - 构造是私有的

        //反射技术 - 破坏程序的封装性 - 一切框架底层技术.
        //反射技术破坏了单例模式

        //反射代码 - 功能
        //1. 获取class实例
        Class<?> c = Single04Demo.class;

        //2. 反射构造对应的反射实例
        try {
            Constructor<?> constructor = c.getDeclaredConstructor();

            //因为构造是私有,反射设置可访问
            constructor.setAccessible(true);

            //反射调用构造方法
            try {
                Single04Demo s1 = (Single04Demo) constructor.newInstance();
                Single04Demo s2 = (Single04Demo) constructor.newInstance();
                System.out.println(s1);
                System.out.println(s2);
                System.out.println(s1 == s2);//false

            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}

class ReflectDemo02{
    public static void main(String[] args) {
        //1. 获取class实例 - 反射技术的基础类
        Class<?> c = Single05Demo.class;

        //2. 获取构造对应的反射实例
        try {
            Constructor<?> constructor = c.getDeclaredConstructor(String.class,int.class);

            //设置访问为可见的
            constructor.setAccessible(true);

            //反射调用构造方法
            try {
                //反射获取枚举的单例 - java.lang.IllegalArgumentException: Cannot reflectively create enum objects
                Single05Demo s1 = (Single05Demo) constructor.newInstance("INSTANCE",0);
                System.out.println(s1);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}